﻿
namespace Oddo.Concept.Crm.Host.Console
{
    using System;
    using System.IO;
    using System.Linq;
    using System.Web.Http.Dispatcher;
    using System.Web.Http.SelfHost;
    using Microsoft.Practices.ServiceLocation;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.InterceptionExtension;
    using Oddo.Concept.Crm.Common.Modules;

    public abstract class HostBootstrapper : IDisposable
    {
        private readonly IUnityContainer _container;
        private IServerModuleCatalog _moduleCatalog;

        protected HostBootstrapper()
        {
            _container = new UnityContainer();
        }

        protected internal IUnityContainer Container
        {
            get { return _container; }
        }
        
        protected internal IServerModuleCatalog ModuleCatalog
        {
            get { return _moduleCatalog ?? (_moduleCatalog = CreateModuleCatalog()); }
        }

        public HttpSelfHostConfiguration HttpHostConfiguration { get; set; }

        public HttpSelfHostServer HttpHostServer { get; set; }

        public virtual void ConfigureContainer()
        {
            this.Container.AddNewExtension<Interception>();
            this.Container.RegisterType<IServiceLocator,UnityServiceLocatorAdapter>();
            ServiceLocator.SetLocatorProvider(() => this.Container.Resolve<IServiceLocator>(new ResolverOverride[0]));
        }

        public virtual void Initialize()
        {
            ConfigureContainer();
            HttpHostConfiguration.Services.Replace(typeof(IHttpControllerActivator), new UnityControllerActivator(this.Container));
            Container.RegisterInstance(typeof(HttpSelfHostConfiguration), HttpHostConfiguration);
        }

        public abstract IServerModuleCatalog CreateModuleCatalog();

        public void Dispose()
        {
            GC.SuppressFinalize(this);
            _container.Dispose();
            _moduleCatalog = null;
        }
    }

    public class ConsoleHostBootstrapper : HostBootstrapper
    {
        public override IServerModuleCatalog CreateModuleCatalog()
        {
            return new DirectoryServerModuleCatalog(Path.GetFullPath(".\\"));
        }

        public override void Initialize()
        {
            base.Initialize();

            var catalog = this.ModuleCatalog;
            catalog.Initialize();

            foreach (var module in 
                from item in catalog.Items 
                let moduleType = Type.GetType(item.Type) 
                select (IServerModule)this.Container.RegisterType(moduleType, item.Name).Resolve(moduleType))
            {
                module.Initialize();
            }
        }
    }
}